﻿using JavaDevToys.Rcl.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace JavaDevToys.Rcl.Service.Impl
{
    public class ParameterInfoParser : IParameterInfoParser
    {
        public List<ParameterInfo> Parse(string _content)
        {
            List<ParameterInfo> parameterInfos = new List<ParameterInfo>();

            // 分割内容为行
            string[] lines = _content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
            // 使用状态机来跟踪当前解析的部分

            Models.Section currentSection = Models.Section.None;
            // 临时变量
            Regex sectionRegex = new Regex(@"^(入参|出参)\s+(.+)$");
            Regex paramHeaderRegex = new Regex(@"^\s*参数描述\s+参数名\s+必填\s+数据类型\s+备注\s+最后修改时间$");
            Regex paramRowRegex = new Regex(@"^\s*(.+?)\s+(.+?)\s+([YN]?)\s+(\S+)\s*(.*?)\s*$");
            Regex dtoParamRegex = new Regex(@"^【End-.*列表】$");
            Regex dto2ParamRegex = new Regex(@"End-[\u4e00-\u9fa5a-zA-Z]+列表");
            List<string> dtoParamsName = new List<string>();
            bool requestBegin = false;
            bool responseBegin = false;
            int titleIndex = 0;

            for (int i = 0; i < lines.Length; i++)
            {
                var rawLine = lines[i];
                string lastParameterName = string.Empty;
                string line = rawLine.Trim();
                if (string.IsNullOrEmpty(line))
                    continue;
                if (dtoParamRegex.IsMatch(line)|| dto2ParamRegex.IsMatch(line))
                {
                    if (dtoParamsName.Count > 0)
                        dtoParamsName.Remove(dtoParamsName.Last());
                }

                // 检查是否为新的部分
                var sectionMatch = sectionRegex.Match(line);
                if (sectionMatch.Success)
                {
                    string sectionName = sectionMatch.Groups[1].Value.Trim();
                    string sectionContent = sectionMatch.Groups[2].Value.Trim();

                    switch (sectionName)
                    {
                        case "入参":
                            currentSection = Section.RequestParams;
                            requestBegin = true;
                            break;
                        case "出参":
                            currentSection = Section.ResponseParams;
                            responseBegin = true;
                            titleIndex = i;
                            break;
                        default:
                            currentSection = Section.None;
                            break;
                    }
                    continue;
                }

                // 解析参数行
                var paramMatch = paramRowRegex.Match(line);
                if (paramMatch.Success)
                {
                    string description = paramMatch.Groups[1].Value.Trim();
                    string name = paramMatch.Groups[2].Value.Trim();
                    bool isRequired = paramMatch.Groups[3].Value.Trim().Equals("Y", StringComparison.OrdinalIgnoreCase);
                    string dataType = paramMatch.Groups[4].Value.Trim();
                    string remarks = paramMatch.Groups[5].Value.Trim();
                    ParameterInfo param = new ParameterInfo
                    {
                        Description = description,
                        ParameterName = name,
                        IsRequired = isRequired,
                        DataType = dataType,
                        Remarks = remarks
                    };
                    if (IsComplexList(dataType))
                    {
                        if (titleIndex != i - 1&&i!=0)//首个参数为list不添加
                        {
                            lastParameterName = ExtractClassNameFromList(name);
                            dtoParamsName.Add(lastParameterName);
                            param.ComplexResponseParameters.Add(lastParameterName, new List<ParameterInfo>());
                        }else
                            continue;
                        param.DataType = $"List<{ExtractClassNameFromList(name)}>";
                    }
                    
                    if (dtoParamsName.Count > 0 && string.IsNullOrWhiteSpace(lastParameterName))
                    {
                        var dtoParamName = dtoParamsName.Last();
                        parameterInfos.FirstOrDefault(f=> Regex.IsMatch(f.DataType, @$"^List<{dtoParamName}>$")).ComplexResponseParameters[dtoParamName].Add(param);
                        continue;
                    }
                    else
                    {
                        parameterInfos.Add(param);
                    }
                }
            }
            return parameterInfos;
        }
        private bool IsComplexList(string dataType)
        {
            return Regex.IsMatch(dataType, @"^List<\w+>$");
        }

        private string ExtractClassNameFromList(string dataType)
        {
            var match = Regex.Match(dataType, @"^(\w+)List$");
            if (match.Success)
            {
                return $"{match.Groups[1].Value.Substring(0, 1).ToUpper() + match.Groups[1].Value.Substring(1)}Dto";
            }
            return "UnknownClass";
        }

        public string MapCSharpType(string dataType)
        {
            switch (dataType.ToUpper())
            {
                case "LONG":
                    return "long?";
                case "INTEGER":
                    return "int?";
                case "STRING":
                    return "string";
                case "BIGDECIMAL":
                    return "decimal?";
                case "LONG[]":
                    return "long[]";
                case "STRING[]":
                    return "string[]";
                case "LIST<STRING>":
                    return "List<string>";
                case "LIST<INTEGER>":
                    return "List<int>";
                case "LIST<LONG>":
                    return "List<long>";
                case "DATE":
                case "TIME":
                case "DATETIME":
                    return "DateTime?";
                default:
                    break;
            }
            return dataType;
        }

        public List<ParameterInfo> ParseCSharp(string _content)
        {
            List<ParameterInfo> parameterInfos = new List<ParameterInfo>();

            // 分割内容为行
            string[] lines = _content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
            // 使用状态机来跟踪当前解析的部分

            Models.Section currentSection = Models.Section.None;
            // 临时变量
            Regex sectionRegex = new Regex(@"^(入参|出参)\s+(.+)$");
            Regex paramHeaderRegex = new Regex(@"^\s*参数描述\s+参数名\s+必填\s+数据类型\s+备注\s+最后修改时间$");
            Regex paramRowRegex = new Regex(@"^\s*(.+?)\s+(.+?)\s+([YN]?)\s+(\S+)\s*(.*?)\s*$");
            Regex dtoParamRegex = new Regex(@"^【End-.*列表】$");
            Regex dto2ParamRegex = new Regex(@"End-[\u4e00-\u9fa5a-zA-Z]+列表");
            List<string> dtoParamsName = new List<string>();
            bool requestBegin = false;
            bool responseBegin = false;
            int titleIndex = 0;

            for (int i = 0; i < lines.Length; i++)
            {
                var rawLine = lines[i];
                string lastParameterName = string.Empty;
                string line = rawLine.Trim();
                if (string.IsNullOrEmpty(line))
                    continue;
                if (dtoParamRegex.IsMatch(line) || dto2ParamRegex.IsMatch(line))
                {
                    if (dtoParamsName.Count > 0)
                        dtoParamsName.Remove(dtoParamsName.Last());
                }

                // 检查是否为新的部分
                var sectionMatch = sectionRegex.Match(line);
                if (sectionMatch.Success)
                {
                    string sectionName = sectionMatch.Groups[1].Value.Trim();
                    string sectionContent = sectionMatch.Groups[2].Value.Trim();

                    switch (sectionName)
                    {
                        case "入参":
                            currentSection = Section.RequestParams;
                            requestBegin = true;
                            break;
                        case "出参":
                            currentSection = Section.ResponseParams;
                            responseBegin = true;
                            titleIndex = i;
                            break;
                        default:
                            currentSection = Section.None;
                            break;
                    }
                    continue;
                }

                // 解析参数行
                var paramMatch = paramRowRegex.Match(line);
                if (paramMatch.Success)
                {
                    string description = paramMatch.Groups[1].Value.Trim();
                    string name = paramMatch.Groups[2].Value.Trim();
                    bool isRequired = paramMatch.Groups[3].Value.Trim().Equals("Y", StringComparison.OrdinalIgnoreCase);
                    string dataType = MapCSharpType(paramMatch.Groups[4].Value.Trim());
                    string remarks = paramMatch.Groups[5].Value.Trim();
                    ParameterInfo param = new ParameterInfo
                    {
                        Description = description,
                        ParameterName = name,
                        IsRequired = isRequired,
                        DataType = dataType,
                        Remarks = remarks
                    };
                    if (IsComplexList(dataType))
                    {
                        if (titleIndex != i - 1 && i != 0)//首个参数为list不添加
                        {
                            lastParameterName = ExtractClassNameFromList(name);
                            dtoParamsName.Add(lastParameterName);
                            param.ComplexResponseParameters.Add(lastParameterName, new List<ParameterInfo>());
                        }
                        else
                            continue;
                        param.DataType = $"List<{ExtractClassNameFromList(name)}>";
                    }

                    if (dtoParamsName.Count > 0 && string.IsNullOrWhiteSpace(lastParameterName))
                    {
                        var dtoParamName = dtoParamsName.Last();
                        parameterInfos.FirstOrDefault(f => Regex.IsMatch(f.DataType, @$"^List<{dtoParamName}>$")).ComplexResponseParameters[dtoParamName].Add(param);
                        continue;
                    }
                    else
                    {
                        parameterInfos.Add(param);
                    }
                }
            }
            return parameterInfos;
        }
    }
}
